const defaults = {
  title: null,
  message: "",
  type: "",
  showClose: true,
  lockScroll: false,
  closeOnClickModal: true,
  closeOnPressEscape: true,
  closeOnHashChange: true,
  showConfirmButton: true,
  showCancelButton: false,
  confirmButtonText: "",
  cancelButtonText: "",
  beforeClose: null,
  distinguishCancelAndClose:true,
  dangerouslyUseHTMLString: false,
};

import Vue from "vue";
import msgboxVue from "./index.vue";

const MessageBoxConstructor = Vue.extend(msgboxVue);

let currentMsg, instance;
let msgQueue = [];

const initInstance = () => {
  instance = new MessageBoxConstructor({
    el: document.createElement("div"),
  });
};

const showNextMsg = () => {
  // if (!instance) {
  //   initInstance();
  // }
  initInstance();
  if (!instance.visible || instance.closeTimer) {
    if (msgQueue.length > 0) {
      currentMsg = msgQueue.shift();

      let options = currentMsg.options;
      for (let prop in options) {
        if (Object.prototype.hasOwnProperty.call(options, prop)) {
          instance[prop] = options[prop];
        }
      }
      // showNextMsg();
      if (isVNode(instance.message)) {
        instance.$slots.default = [instance.message];
        instance.message = null;
      } else {
        delete instance.$slots.default;
      }
      [
        "modal",
        "showClose",
        "closeOnClickModal",
        "closeOnPressEscape",
        "closeOnHashChange",
      ].forEach((prop) => {
        if (instance[prop] === undefined) {
          instance[prop] = true;
        }
      });

      document.body.appendChild(instance.$el);

      Vue.nextTick(() => {
        if(instance.lockScroll){
          document.body.style.overflow = 'hidden';
        }
        instance.visible = true;
      });
    }
  }
};

const MessageBox = function (options) {
  if (Vue.prototype.$isServer) return;
  if (typeof options === "string" || isVNode(options)) {
    options = {
      message: options,
    };
    if (typeof arguments[1] === "string") {
      options.title = arguments[1];
    }
  }

  msgQueue.push({
    options: merge({}, defaults, MessageBox.defaults, options),
    callback: options.callback,
  });
  showNextMsg();
};

MessageBox.setDefaults = (defaults) => {
  MessageBox.defaults = defaults;
};

MessageBox.close = () => {
  instance.doClose();
  instance.visible = false;
  msgQueue = [];
  currentMsg = null;
};

function merge(target) {
  for (let i = 1, j = arguments.length; i < j; i++) {
    let source = arguments[i] || {};
    for (let prop in source) {
      if (Object.prototype.hasOwnProperty.call(source, prop)) {
        let value = source[prop];
        if (value !== undefined) {
          target[prop] = value;
        }
      }
    }
  }
  return target;
}

function isVNode(node) {
  return (
    node !== null &&
    typeof node === "object" &&
    hasOwn(node, "componentOptions")
  );
}

function hasOwn(obj, key) {
  return hasOwnProperty.call(obj, key);
}

export default MessageBox;
export { MessageBox };
